import type { UseFetchOptions } from 'nuxt/app';
import { useNuxtApp } from '#app';

type Methods = 'GET' | 'POST' | 'PUT' | 'DELETE';

const BASE_URL = '/api';

export interface IResultData<T> {
  code: number;
  data: T;
  msg: string;
}

class HttpRequest {
  request<T = any>(url: string, method: Methods, data?: any, options?: UseFetchOptions<T>) {
    return new Promise((resolve, reject) => {
      const newOptions: UseFetchOptions<T> = {
        baseURL: BASE_URL,
        method,
        ...options,
      };
      const token = useCookie('token');
      if (token.value) {
        newOptions.headers = {
          ...newOptions.headers,
          Authorization: `Bearer ${token.value}`,
        };
      }

      // 根据请求方法处理参数
      if (method === 'GET' || method === 'DELETE') {
        newOptions.params = data;
      } else if (method === 'POST' || method === 'PUT') {
        newOptions.body = data;
      }

      const nuxtApp = useNuxtApp();
      const fetchMethod = (process.client && !nuxtApp.isHydrating) ? nuxtApp.$request : useFetch as any;
      fetchMethod(url, newOptions).then((res: any) => {
        const data = res.data?.value || res;
        if (data.code === 200) {
          resolve(data);
        } else if (data.code === 403) {
          // 跳转到登录页
          ElMessage.error('登录已过期，请重新登录');
          setTimeout(() => {
            const router = useRouter();
            const localePath = useLocalePath();
            router.push(localePath('/login'));
          }, 1000);
        } else if (data.code === 400) {
          ElMessage.error(data.msg);
        }
      })
      .catch((error: any) => {
        let errorMessage = '服务器错误';
        if (error.response && error.response._data) {
          let data = error.response._data;
          if (typeof error.response._data === 'string') {
            try {
              data = JSON.parse(error.response._data);
            } catch (e) {
              errorMessage = error.response._data;
            }
          }
          if (data.errors) {
            const errorMessages = [];
            for (const key in data.errors) {
              errorMessages.push(`${data.errors[key].join(', ')}`);
            }
            errorMessage = errorMessages.join('；') || errorMessage;
          } else {
            errorMessage = data.message || errorMessage;
          }
        }
        if (process.client) {
          ElMessage.error(errorMessage);
        }
        if (error.response && [40001, 40002, 40003].includes(error.response._data.code)) {
          resolve(error.response._data);
        }
        reject(error.response ? error.response._data : errorMessage);
      });
    });
  }

  get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'GET', params, options);
  }

  post<T = any>(url: string, data?: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'POST', data, options);
  }

  put<T = any>(url: string, data?: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'PUT', data, options);
  }

  delete<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
    return this.request(url, 'DELETE', params, options);
  }
}

const httpRequest = new HttpRequest();
export default httpRequest;